﻿using Prism.Dialogs;
using RS.Win32API;
using RS.Win32API.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Threading;
using ZuesControls.Commons;
using ZuesControls.Interfaces;
using ZuesControls.Models;

namespace ZuesControls.Controls
{
    //实现加载动画，弹出消息接口
    public class ZSWindow : ZSWindowbase,ILoading,IMessage,IProgressBarLoading
    {
        private Border PART_EffectBorder;
        static ZSWindow()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ZSWindow), new FrameworkPropertyMetadata(typeof(ZSWindow)));
        }

        public ZSWindow()
        {
            #region 这里样式必须在构造函数配置
            WindowStyle = WindowStyle.None;
            //this.Style = (Style)Application.Current.FindResource("ZS.Style.Window");
            AllowsTransparency = true;
            #endregion
            this.CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, CloseWindow, CanCloseWindow));
            this.CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, MinimizeWindow, CanMinimizeWindow));
            this.CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, MaximizeRestoreWindow, CanMaximizeWindow));
            this.CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, MaximizeRestoreWindow, CanRestoreWindow));
            this.CommandBindings.Add(new CommandBinding(ZSCommands.CleanTextCommand, CleanTextText));
            this.CommandBindings.Add(new CommandBinding(ZSCommands.CloseProgressBarCommand, OnCloseProgressBarCommandExcute));
        }


        #region 变量

        private Button PART_Minimize;
        private Button PART_BtnMaxRestore;
        private Button PART_BtnClose;
        private ZSDialog PART_WinContentHost;
        private DispatcherTimer InfoBarTimer;
        #endregion

        #region 属性

        public static readonly DependencyProperty IconCornerRadiusProperty =
            DependencyProperty.Register("IconCornerRadius", typeof(CornerRadius), typeof(ZSWindow), new PropertyMetadata(new CornerRadius(10)));

        public static readonly DependencyProperty IsShowTitleProperty =
            DependencyProperty.Register("IsShowTitle", typeof(bool), typeof(ZSWindow), new PropertyMetadata(true));

        public static readonly DependencyProperty BorderCornerRadiusProperty =
            DependencyProperty.Register("BorderCornerRadius", typeof(CornerRadius), typeof(ZSWindow), new PropertyMetadata(new CornerRadius(0)));

        public static readonly DependencyProperty IconWidthProperty =
            DependencyProperty.Register("IconWidth", typeof(double), typeof(ZSWindow), new PropertyMetadata(20D));

        public static readonly DependencyProperty IconHeightProperty =
            DependencyProperty.Register("IconHeight", typeof(double), typeof(ZSWindow), new PropertyMetadata(20D));

        public static readonly DependencyProperty IconMarginProperty =
            DependencyProperty.Register("IconMargin", typeof(Thickness), typeof(ZSWindow), new PropertyMetadata(new Thickness(5, 0, 0, 0)));

        public static readonly DependencyProperty LeftCaptionContentProperty =
            DependencyProperty.Register("LeftCaptionContent", typeof(object), typeof(ZSWindow), new PropertyMetadata(null));

        public static readonly DependencyProperty MidCaptionContentProperty =
            DependencyProperty.Register("MidCaptionContent", typeof(object), typeof(ZSWindow), new PropertyMetadata(null));

        public static readonly DependencyProperty IsFitSystemProperty =
            DependencyProperty.Register("IsFitSystem", typeof(bool), typeof(ZSWindow), new PropertyMetadata(false));

        public static readonly DependencyProperty InfoBarModelProperty =
            DependencyProperty.Register("InfoBarModel", typeof(InfoBarModel), typeof(ZSWindow), new PropertyMetadata(null, OnInfoBarModelPropertyChanged));

        public static readonly DependencyProperty IsShowWinBtnCommandsProperty =
            DependencyProperty.Register("IsShowWinBtnCommands", typeof(bool), typeof(ZSWindow), new PropertyMetadata(true));

        public static readonly DependencyProperty InfoBarCloseDelayProperty =
            DependencyProperty.Register("InfoBarCloseDelay", typeof(int), typeof(ZSWindow), new PropertyMetadata(5000));


        public static readonly DependencyProperty CaptionHeightProperty =
            DependencyProperty.Register("CaptionHeight", typeof(double), typeof(ZSWindow), new PropertyMetadata(32D));


        public static readonly DependencyProperty ButtonHeightProperty =
            DependencyProperty.Register("ButtonHeight", typeof(double), typeof(ZSWindow), new PropertyMetadata(25.0));
        #endregion

        #region 私有方法

        private void CanCloseWindow(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }
        private void CanRestoreWindow(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this.WindowState == WindowState.Maximized;
        }

        private void CanMaximizeWindow(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void CanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void MaximizeRestoreWindow(object sender, ExecutedRoutedEventArgs e)
        {
            if (this.WindowState == WindowState.Maximized)
            {
                SystemCommands.RestoreWindow(this);
            }
            else
            {
                SystemCommands.MaximizeWindow(this);
            }
        }

        private void MinimizeWindow(object sender, ExecutedRoutedEventArgs e)
        {
            SystemCommands.MinimizeWindow(this);
        }

        private void CloseWindow(object sender, ExecutedRoutedEventArgs e)
        {
            SystemCommands.CloseWindow(this);
        }
        protected virtual void OnCloseProgressBarCommandExcute(object sender, ExecutedRoutedEventArgs e)
        {
            // 默认什么也不做
        }

        private static void OnInfoBarModelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var rsWindow = d as ZSWindow;
            if (rsWindow.InfoBarModel == null)
            {
                return;
            }
            rsWindow.InfoBarTimer?.Stop();
            // 初始化定时器
            rsWindow.InfoBarTimer = new DispatcherTimer();
            // 设置定时器的间隔为 3 秒
            rsWindow.InfoBarTimer.Interval = TimeSpan.FromMilliseconds(rsWindow.InfoBarCloseDelay);
            // 为定时器的 Tick 事件添加处理程序
            rsWindow.InfoBarTimer.Tick += rsWindow.InfoBarTimer_Tick;
            // 启动定时器
            rsWindow.InfoBarTimer.Start();
        }
       
        private void InfoBarTimer_Tick(object? sender, EventArgs e)
        {
           
            this.InfoBarTimer.Stop();
            this.InfoBarTimer = null;
            this.Dispatcher.Invoke(() =>
            {
                this.InfoBarModel = null;
            });
        }

        private void CleanTextText(object sender, ExecutedRoutedEventArgs e)
        {
            ZSCommands.CleanText(e.Parameter);
        }
        private void ZSWindowBase_Activated(object? sender, EventArgs e)
        {

        }


        #endregion

        #region 属性设置

        [Description("标题栏高度设置")]
        [Browsable(true)]
        [Category("自定义窗口样式")]
        public double CaptionHeight
        {
            get { return (double)GetValue(CaptionHeightProperty); }
            set { SetValue(CaptionHeightProperty, value); }
        }

        [Description("标题栏高度设置")]
        [Browsable(true)]
        [Category("自定义窗口样式")]
        public double ButtonHeight
        {
            get { return (double)GetValue(ButtonHeightProperty); }
            set { SetValue(ButtonHeightProperty, value); }
        }

        [Description("消息提示自动关闭时间 单位毫秒")]
        public int InfoBarCloseDelay
        {
            get { return (int)GetValue(InfoBarCloseDelayProperty); }
            set { SetValue(InfoBarCloseDelayProperty, value); }
        }

        [Description("是否显示窗体关闭放大缩小按钮")]
        [Browsable(true)]
        public bool IsShowWinBtnCommands
        {
            get { return (bool)GetValue(IsShowWinBtnCommandsProperty); }
            set { SetValue(IsShowWinBtnCommandsProperty, value); }
        }

        [Description("消息")]
        public InfoBarModel InfoBarModel
        {
            get { return (InfoBarModel)GetValue(InfoBarModelProperty); }
            set { SetValue(InfoBarModelProperty, value); }
        }

        [Description("是否沉浸式")]
        [Browsable(true)]
        [Category("自定义窗口样式")]
        public bool IsFitSystem
        {
            get { return (bool)GetValue(IsFitSystemProperty); }
            set { SetValue(IsFitSystemProperty, value); }
        }


        [Description("自定义中部标题栏内容")]
        [Browsable(false)]
        public object MidCaptionContent
        {
            get { return (object)GetValue(MidCaptionContentProperty); }
            set { SetValue(MidCaptionContentProperty, value); }
        }

        [Description("圆角边框大小")]
        [Browsable(true)]
        [Category("自定义窗口样式")]


        public double IconWidth
        {
            get { return (double)GetValue(IconWidthProperty); }
            set { SetValue(IconWidthProperty, value); }
        }

        [Description("自定义左侧标题栏内容")]
        [Browsable(false)]
        public object LeftCaptionContent
        {
            get { return (object)GetValue(LeftCaptionContentProperty); }
            set { SetValue(LeftCaptionContentProperty, value); }
        }

        public CornerRadius BorderCornerRadius
        {
            get { return (CornerRadius)GetValue(BorderCornerRadiusProperty); }
            set { SetValue(BorderCornerRadiusProperty, value); }
        }



        public CornerRadius IconCornerRadius
        {
            get { return (CornerRadius)GetValue(IconCornerRadiusProperty); }
            set { SetValue(IconCornerRadiusProperty, value); }
        }

        public double IconHeight
        {
            get { return (double)GetValue(IconHeightProperty); }
            set { SetValue(IconHeightProperty, value); }
        }


        [Description("是否显示标题")]
        public bool IsShowTitle
        {
            get { return (bool)GetValue(IsShowTitleProperty); }
            set { SetValue(IsShowTitleProperty, value); }
        }



        public Thickness IconMargin
        {
            get { return (Thickness)GetValue(IconMarginProperty); }
            set { SetValue(IconMarginProperty, value); }
        }



        #endregion

        #region 公有方法
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.PART_Minimize = this.GetTemplateChild(nameof(this.PART_Minimize)) as Button;
            this.PART_BtnMaxRestore = this.GetTemplateChild(nameof(this.PART_BtnMaxRestore)) as Button;
            this.PART_BtnClose = this.GetTemplateChild(nameof(this.PART_BtnClose)) as Button;
            this.PART_WinContentHost = this.GetTemplateChild(nameof(this.PART_WinContentHost)) as ZSDialog;
            this.PART_EffectBorder = this.GetTemplateChild(nameof(PART_EffectBorder)) as Border;
          //  PART_EffectBorder.Margin = new Thickness(15);
        }
        //加载动画、执行任务
        public Task<OperateResult> InvokeAsync(Func<CancellationToken, Task<OperateResult>> func, CancellationToken cancellationToken = default)
        {
            return this.Loading.InvokeAsync(func, cancellationToken);
        }

        public Task<OperateResult<T>> InvokeAsync<T>(Func<CancellationToken, Task<OperateResult<T>>> func, CancellationToken cancellationToken = default)
        {
            return this.Loading.InvokeAsync(func, cancellationToken);
        }
              
        //消息弹出框
        public async Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText = null, string caption = null, MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.None, MessageBoxOptions options = MessageBoxOptions.None)
        {
            return await this.MessageBox.ShowMessageAsync(window, messageBoxText, caption, button, icon, defaultResult, options);
        }


        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText, string caption)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText, string caption, MessageBoxButton button)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText)
        {
           return this.MessageBox.ShowMessageAsync(window, messageBoxText);
        }

        public Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText, string caption)
        {
            throw new NotImplementedException();
        }

        public async Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText, string caption, MessageBoxButton button)
        {
           return await this.MessageBox.ShowMessageAsync(window,messageBoxText,caption,button);
        }

        public Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
        {
            throw new NotImplementedException();
        }
        public void HideLoading()
        {
            this.Loading.HideLoading();
        }

        public void ShowLoading()
        {
            this.Loading.ShowLoading();
        }

        public void HandleBtnClickEvent()
        {
            this.MessageBox.HandleBtnClickEvent();
        }

        public void MessageBoxDisplay(Window window)
        {
            this.MessageBox.MessageBoxDisplay(window);
        }

        public void MessageBoxClose()
        {
            this.MessageBox.MessageBoxClose();
        }
        public void SetProgressBarValue(double Value)
        {
            this.PART_WinContentHost.SetProgressBarValue(Value);
          
        }

        public Task<OperateResult> ShowProgressBarLoadingAsync(Func<CancellationToken, Task<OperateResult>> func, CancellationToken cancellationToken = default)
        {
            return this.PART_WinContentHost.ShowProgressBarLoadingAsync(func, cancellationToken);
        }

        public Task<OperateResult<T>> ShowProgressBarLoadingAsync<T>(Func<CancellationToken, Task<OperateResult<T>>> func, CancellationToken cancellation = default)
        {
            throw new NotImplementedException();
        }

       

        #endregion

        #region 接口获取
        public ILoading Loading
        {
            get
            {
                return this.PART_WinContentHost?.Loading;
            }
        }

        public IMessage MessageBox
        {
            get
            {
                return this.PART_WinContentHost?.MessageBox;
            }
        }
        #endregion


    }
}
